<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <style>
      body {
        padding: 50px;
        background: #34495e;
      }
      input {
        border: solid 10px #ddd;
        height: 30px;
      }
      .error {
        border: solid 10px red;
      }
    </style>
    <body>
      <input type="text" validate rule="max:12,min:3" />
      <input type="text" validate rule="max:3,isNumber" />
    </body>
    <script>
      "use strict";
      //验证处理类
      class Validate {
        max(value, len) {
          return value.length <= len;
        }
        min(value, len) {
          return value.length >= len;
        }
        isNumber(value) {
          return /^\d+$/.test(value);
        }
      }

      //代理工厂
      function makeProxy(target) {
        return new Proxy(target, {
          get(target, key) {
            return target[key];
          },
          set(target, key, el) {
            const rule = el.getAttribute("rule");
            const validate = new Validate();
            let state = rule.split(",").every((rule) => {
              const info = rule.split(":");
              return validate[info[0]](el.value, info[1]);
            });
            el.classList[state ? "remove" : "add"]("error");
            return true;
          },
        });
      }

      const nodes = makeProxy(document.querySelectorAll("[validate]"));
      console.log(nodes);

      nodes.forEach((item, i) => {
        item.addEventListener("keyup", function () {
          nodes[i] = this;
        });
      });
    </script>
  </body>
</html>
